package io.finer.erp.jeecg.stock.service.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import io.finer.erp.jeecg.stock.vo.StkPickUpBillVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.FillRuleUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.client.util.Lists;
import com.google.common.collect.ImmutableList;

import cn.hutool.core.lang.UUID;
import io.finer.erp.jeecg.bas.entity.BasMaterial;
import io.finer.erp.jeecg.bas.entity.BasMaterialCategory;
import io.finer.erp.jeecg.bas.entity.ZrkOrderProcess;
import io.finer.erp.jeecg.bas.entity.ZrkQzOrdeDetail;
import io.finer.erp.jeecg.bas.entity.ZzDeviceType;
import io.finer.erp.jeecg.bas.entity.ZzShoporder;
import io.finer.erp.jeecg.bas.service.IBasMaterialCategoryService;
import io.finer.erp.jeecg.bas.service.IBasMaterialService;
import io.finer.erp.jeecg.bas.service.IZrkOrderProcessService;
import io.finer.erp.jeecg.bas.service.IZrkQzOrdeDetailService;
import io.finer.erp.jeecg.bas.service.IZzDeviceTypeService;
import io.finer.erp.jeecg.bas.service.IZzShoporderService;
import io.finer.erp.jeecg.stock.entity.StkInventory;
import io.finer.erp.jeecg.stock.entity.StkPickUpBill;
import io.finer.erp.jeecg.stock.entity.StkPickUpEntry;
import io.finer.erp.jeecg.stock.mapper.StkPickUpBillMapper;
import io.finer.erp.jeecg.stock.mapper.StkPickUpEntryMapper;
import io.finer.erp.jeecg.stock.service.IStkInventoryService;
import io.finer.erp.jeecg.stock.service.IStkPickUpBillService;
import io.finer.erp.jeecg.stock.service.IStkPickUpEntryService;

/**
 * @Description: 提货单
 * @Author: jeecg-boot
 * @Date:   2020-11-10
 * @Version: V1.0
 */
@Service
public class StkPickUpBillServiceImpl extends ServiceImpl<StkPickUpBillMapper, StkPickUpBill> implements IStkPickUpBillService {

	@Autowired
	private StkPickUpBillMapper stkPickUpBillMapper;
	@Autowired
	private StkPickUpEntryMapper stkPickUpEntryMapper;
	@Autowired
	private IZrkOrderProcessService processService;
	@Autowired
	private IZzShoporderService zzShoporderService;
	@Autowired
	private IBasMaterialService materialService;
	@Autowired
	private IStkPickUpEntryService pickUpEntryService;
	@Autowired
	private IStkInventoryService inventoryService;
	@Autowired
	private IZrkQzOrdeDetailService detailService;
	@Autowired
	private IZzDeviceTypeService zzDeviceTypeService;
	@Autowired
	private IBasMaterialCategoryService categoryService;
	@Autowired
	private ISysBaseAPI baseApi;
	
	@Override
	@Transactional
	public void delMain(String id) {
		stkPickUpEntryMapper.deleteByMainId(id);
		stkPickUpBillMapper.deleteById(id);
	}
	@Override
	public Page<StkPickUpBillVo> selectUpBill(IPage<StkPickUpBillVo> page,String billNo,String mesId,String deviceId,
											  String billStatus,String isPush){


		return stkPickUpBillMapper.selectUpBill(page,billNo,mesId,deviceId,billStatus,isPush);
	}



	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			stkPickUpEntryMapper.deleteByMainId(id.toString());
			stkPickUpBillMapper.deleteById(id);
		}
	}

	@Override
	public Result<?> addPickUp(String processId) {
		ZrkOrderProcess orderProcess = processService.getById(processId);
		if(null == orderProcess) {
			return Result.error("未找到生产订单工序。");
		}
		//不能重复生成
		String orderId = orderProcess.getOrderId();
		ZzShoporder zzShoporder = zzShoporderService.getById(orderId);
		if(null != selectByProcessId(processId)) {
			return Result.error("提货单已存在，不能重复生成。");
		}
		StkPickUpBill bill = new StkPickUpBill();
		bill.setProcessId(processId);
		bill.setOrderId(zzShoporder.getId());
		String billNo = baseApi.getNoByCode("pick_up_bill_no");
		bill.setBillNo(billNo);
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		bill.setCreateBy(sysUser.getUsername());
		bill.setCreateTime(DateUtils.gettimestamp());
		bill.setIsEnabled(1);
		bill.setBillStatus("0");
		bill.setDeviceId(orderProcess.getDeviceId());
		//获取详细信息
		String paperSupplier = zzShoporder.getPaperSupplier();//底纸供应商paper_supplier
		String glueSupplier = zzShoporder.getGlueSupplier();//胶水供应商glue_supplier
		String facialSupplier = zzShoporder.getFacialSupplier();//面纸供应商facial_supplier
		String woPartname = zzShoporder.getWoPartname();//物料
		String model = zzShoporder.getSpecs();//规格
		Integer number = zzShoporder.getWoQuantity();//数量
		bill.setParameter(paperSupplier);
		bill.setGlueSupplier(glueSupplier);
		bill.setFacialSupplier(facialSupplier);
		bill.setModel(model);
		bill.setNumber(new BigDecimal(number));
		//查询工序信息
		ZzDeviceType zzDeviceType = zzDeviceTypeService.getById(orderProcess.getProcessId());
		String typeName = zzDeviceType.getDeviceTpyeName();
		if(typeName.contains("分切")) {
			String fqCategory = orderProcess.getFqCategory();
			BasMaterialCategory category = this.categoryService.getById(fqCategory);
			String categoryName = category.getName();
			bill.setMaterial(categoryName);
			String params = orderProcess.getFqParams() + "," + orderProcess.getFqLength();
			bill.setParameter(params);
		} else {
			BasMaterial material = this.materialService.getById(woPartname);
			bill.setMaterial(material.getName());
		}
		
		boolean flag = this.save(bill);
		if(flag) {
			return Result.ok();
		} else {
			return Result.error("生成失败。");
		}
	}
	
	public StkPickUpBill selectByProcessId(String processId) {
		LambdaQueryWrapper<StkPickUpBill> query = new LambdaQueryWrapper<>();
		query.eq(StkPickUpBill::getProcessId, processId);
		List<StkPickUpBill> list = list(query);
		if(list != null && list.size() != 0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public Result<?> addPicupEntry(String materialId, String ids) {
		StkPickUpBill bill = this.getById(ids);
		if(null == bill) {
			return Result.error("未找到对应的提货单。");
		}
		if(StringUtils.isBlank(materialId)) {
			return Result.error("未传入物料信息。");
		}
		String[] materialCodes = StringUtils.split(materialId, ",");
		List<String> codeList = ImmutableList.copyOf(materialCodes);
		List<BasMaterial> materialList = this.materialService.getByCodes(codeList);
		if(null == materialList || 0 == materialList.size()) {
			return Result.error("未传入物料信息。");
		}
		Date date = DateUtils.gettimestamp();
		List<StkPickUpEntry> entryList = Lists.newArrayList();
		for (BasMaterial material : materialList) {
			LambdaQueryWrapper<StkPickUpEntry> entryQuery = new LambdaQueryWrapper<>();
			entryQuery.eq(StkPickUpEntry::getMaterialId, material.getId());
			entryQuery.eq(StkPickUpEntry::getIsOut, 0);
			List<StkPickUpEntry> preEntryList = this.pickUpEntryService.list(entryQuery);
			if(0 != preEntryList.size()) {
				return Result.error("编码为" + material.getCode() + "的物料已经在其他的提货单中");
			}
			
			StkPickUpEntry entry = new StkPickUpEntry();
			entry.setBillId(ids);
			LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
			entry.setCreateBy(sysUser.getUsername());
			entry.setCreateTime(date);
			entry.setMaterialCode(material.getCode());
			entry.setMaterialId(material.getId());
			entry.setSysOrgCode(sysUser.getOrgCode());
			entry.setIsOut("0");
			StkInventory inventory = this.inventoryService.selectLatestByMaterial(material.getId());
			if(null == inventory) {
				return Result.error("编码为" + material.getCode() + "的物料库存异常，请检查");
			}
			entry.setWarehouseId(inventory.getWarehouseId());
			entryList.add(entry);
		}
		if(0 < entryList.size()) {
			this.pickUpEntryService.saveBatch(entryList);
		}
		return Result.ok("成功");
	}

	@Override
	public Result<?> getCutting(String id) {	
		StkPickUpBill bill = getById(id);
		Page<ZrkQzOrdeDetail> page = new Page<ZrkQzOrdeDetail>(0, 20);
		if(null == bill) {
			LambdaQueryWrapper<ZrkQzOrdeDetail> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(ZrkQzOrdeDetail::getId, UUID.randomUUID().toString());
			IPage<ZrkQzOrdeDetail> pageList = detailService.page(page, queryWrapper);
			return Result.ok(pageList);
		}
		String processId = bill.getProcessId();
		LambdaQueryWrapper<ZrkQzOrdeDetail> query = new LambdaQueryWrapper<>();
		query.eq(ZrkQzOrdeDetail::getZrkQzOrderId, processId);
		IPage<ZrkQzOrdeDetail> pageList = detailService.page(page, query);
		return Result.ok(pageList);
	}

	@Override
	public List<StkPickUpBill> getByMesId(String mesId) {
		LambdaQueryWrapper<StkPickUpBill> query = new LambdaQueryWrapper<>();
		query.eq(StkPickUpBill::getMesId, mesId);
		return list(query);
	}
}
